package com.idealighter.game.games.blackjack.manager;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.idealighter.game.core.common.Game;
import com.idealighter.game.core.constant.room.RoomActiveConstant;
import com.idealighter.game.dictionary.dic.BlackjackRoomDic;
import com.idealighter.game.dictionary.dic.GamesDic;
import com.idealighter.game.dictionary.domain.BlackjackRoomDomain;
import com.idealighter.game.dictionary.domain.GamesDomain;
import com.idealighter.game.games.blackjack.struct.BlackjackBaseRoom;
import com.idealighter.game.games.blackjack.struct.BlackjackRoom;
import com.idealighter.game.games.blackjack.struct.BlackjackSeat;
import com.idealighter.game.games.blackjack.struct.BlackjackTable;
import com.idealighter.game.games.common.InstanceState;
import com.idealighter.utils.check.EmptyUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class BlackjackDataMgr {

  private static final Logger LOG = LoggerFactory.getLogger(BlackjackDataMgr.class);

  private final Map<Long, BlackjackSeat> playerSeats = new HashMap<>();
  // 21点游戏房间
  private final Map<Integer, BlackjackBaseRoom> roomMap = new HashMap<>();

  private BlackjackRoomDic roomDic;

  private final GamesDic gamesDic;

  /**
   * 构造函数.
   * 
   * @param roomDic 房间字典.
   * @param gamesDic 游戏字典.
   */
  @Inject
  public BlackjackDataMgr(BlackjackRoomDic roomDic, GamesDic gamesDic) {
    this.roomDic = roomDic;
    this.gamesDic = gamesDic;
    createRooms();
  }



  /**
   * 创建房间 .
   *
   * @author abin
   * @date 2018年4月28日 下午2:10:42
   * @param roomDomain 房间dic信息.
   */
  private void createRoom(BlackjackRoomDomain roomDomain) {
    if (roomDomain != null && roomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
      GamesDomain gamesDom = gamesDic.get(Game.BLACK_JACK.getType());
      if (gamesDom != null && gamesDom.getActive()) {
        this.roomMap.put(roomDomain.getId(), new BlackjackBaseRoom(roomDomain));
        LOG.info("[21点]创建房间[{}][{}]", roomDomain.getId(), roomDomain.getName());
      }
    }
  }

  /**
   * 创建房间.
   * 
   * @return 房间map.
   */
  private void createRooms() {

    List<BlackjackRoomDomain> roomDomains = roomDic.list();
    if (EmptyUtil.listIsNotEmpty(roomDomains)) {
      for (BlackjackRoomDomain roomDomain : roomDomains) {
        createRoom(roomDomain);

      }
    }
  }

  /**
   * 重新加载房间.
   *
   * @author abin
   * @date 2018年5月18日 上午11:31:12
   * @return 需要开启的房间id.
   */
  public List<Integer> reloadRoom() {
    roomDic.load();
    List<Integer> ids = new ArrayList<>();
    GamesDomain gamesDom = gamesDic.get(Game.BLACK_JACK.getType());
    if (gamesDom != null && gamesDom.getActive()) {
      List<BlackjackRoomDomain> rooms = roomDic.list();
      if (EmptyUtil.listIsNotEmpty(rooms)) {
        for (BlackjackRoomDomain roomDomain : rooms) {
          if (roomDomain != null && roomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            ids.add(roomDomain.getId());
          }
        }
      }
    }
    return ids;
  }

  /**
   * 开启房间.
   *
   * @author abin
   * @date 2018年4月28日 下午2:14:26
   * @param roomId 房间id.
   * @return return old room(delete) list.
   */
  public List<BlackjackRoom> startRoom(int roomId, boolean reload) {
    if (reload) {
      roomDic.load();
    }
    List<BlackjackRoom> deleteRooms = new ArrayList<>();

    GamesDomain gamesDom = gamesDic.get(Game.BLACK_JACK.getType());
    if (gamesDom != null && gamesDom.getActive()) {
      BlackjackRoomDomain roomDomain = roomDic.get(roomId);

      if (roomDomain != null && roomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
        BlackjackBaseRoom baseRoom = roomMap.get(roomId);

        if (baseRoom == null) {
          createRoom(roomDomain);
        } else {
          deleteRooms = baseRoom.renewRoom(roomDomain);
        }
      }
    }
    return deleteRooms;
  }

  /**
   * 获取最新房间实例.
   * 
   * @param roomId 房间id.
   * @return 21点房间.
   */
  public BlackjackRoom getNewestRoom(int roomId) {
    BlackjackRoom room = null;
    BlackjackBaseRoom baseRoom = roomMap.get(roomId);
    if (baseRoom != null) {
      room = baseRoom.getNewInstance();
    }
    return room;
  }


  /**
   * 获取所有实例 .
   *
   * @author abin
   * @date 2018年4月28日 下午4:32:06
   * @param roomId 房间id.
   * @return 获取所有实例.
   */
  public List<BlackjackRoom> deleteRoom(int roomId) {
    roomDic.load();
    List<BlackjackRoom> rooms = null;
    BlackjackBaseRoom baseRoom = roomMap.get(roomId);
    if (baseRoom != null) {
      rooms = new ArrayList<>(baseRoom.deleteAllInstance());
    }
    return rooms;
  }

  /**
   * 实例id获取房间实例 .
   *
   * @author abin
   * @date 2018年4月27日 下午6:01:41
   * @param instanceId 实例id.
   * @return 21点房间.
   */
  public BlackjackRoom getRoomByIntanceId(int instanceId) {
    BlackjackRoom room = null;
    int roomId = getRoomIdByIntanceId(instanceId);
    BlackjackBaseRoom baseRoom = roomMap.get(roomId);
    if (baseRoom != null) {
      room = baseRoom.getByInstanceId(instanceId);
    }
    return room;
  }


  /**
   * 校验是否remove room.
   *
   * @author abin
   * @date 2018年4月28日 下午7:39:33
   * @param baseRoom 基本房间.
   */
  public void checkRemoveRoom(BlackjackBaseRoom baseRoom) {
    if (baseRoom.allInstance() == null || baseRoom.allInstance().isEmpty()) {
      roomMap.remove(baseRoom.getRoomId());
      baseRoom = null;
    }

  }

  /**
   * 清空房间实例.
   *
   * @author abin
   * @date 2018年4月28日 下午5:55:32
   * @param roomId 房间id.
   * @param instanceId 实例id.
   */
  public boolean checkRemoveInstance(int roomId, int instanceId) {
    boolean remove = false;
    BlackjackBaseRoom baseRoom = roomMap.get(roomId);
    if (baseRoom != null) {
      BlackjackRoom room = baseRoom.getByInstanceId(instanceId);

      Collection<BlackjackTable> tables = room.tables();

      if (tables == null || tables.isEmpty()) {
        baseRoom.removeInstance(instanceId);
        checkRemoveRoom(baseRoom);
        remove = true;
      }
    }
    return remove;
  }

  /**
   * 获取所有最新的房间.
   * 
   * @return 21点房间列表.
   */
  public Collection<BlackjackRoom> newestRooms() {
    List<BlackjackRoom> tempRooms = new ArrayList<>();
    for (BlackjackBaseRoom baseRoom : roomMap.values()) {
      BlackjackRoom blackjackRoom = baseRoom.getNewInstance();
      if (blackjackRoom != null && blackjackRoom.getInstanceState().equals(InstanceState.NORMAL)) {
        tempRooms.add(blackjackRoom);
      }
    }
    return tempRooms;
  }

  /**
   * 获取所有的房间列表 .
   *
   * @author abin
   * @date 2018年4月27日 下午4:22:40
   * @return 所有的房间列表.
   */
  public Collection<BlackjackRoom> allRooms() {
    List<BlackjackRoom> tempRooms = new ArrayList<>();
    for (BlackjackBaseRoom baseRoom : roomMap.values()) {
      Collection<BlackjackRoom> allInstances = baseRoom.allInstance();
      if (allInstances != null && !allInstances.isEmpty()) {
        tempRooms.addAll(allInstances);
      }
    }
    return tempRooms;
  }

  public Collection<BlackjackBaseRoom> allBaseRoom() {
    return roomMap.values();
  }



  /**
   * 获取牌桌.
   * 
   * @param tableId 桌子id.
   * @return 21点桌子.
   */
  public BlackjackTable getTable(int tableId) {
    BlackjackTable table = null;
    int roomId = getRoomIdByTableId(tableId);
    BlackjackBaseRoom baseRoom = roomMap.get(roomId);
    if (baseRoom != null) {
      int instanceId = getInstanceIdByTableId(tableId);
      BlackjackRoom room = baseRoom.getByInstanceId(instanceId);
      if (room != null) {
        table = room.getTables().get(tableId);
      }
    }
    return table;
  }

  /**
   * 根据桌子id计算房间实例id.
   * 
   * @param tableId 桌子Id.
   * @return 房间Id.
   */
  public int getInstanceIdByTableId(int tableId) {
    return tableId / BlackjackTable.MAX_TABLE;
  }

  /**
   * 根据实例id计算房间id .
   *
   * @author abin
   * @date 2018年4月27日 下午5:54:05
   * @param instanceId 实例id.
   * @return 房间id.
   */
  public int getRoomIdByIntanceId(int instanceId) {
    return instanceId / BlackjackRoom.MAX_INSTANCE;
  }

  /**
   * 根据桌子获取房间id .
   *
   * @author abin
   * @date 2018年4月27日 下午5:56:03
   * @param tableId 桌子id.
   * @return 房间id.
   */
  public int getRoomIdByTableId(int tableId) {
    return getRoomIdByIntanceId(getInstanceIdByTableId(tableId));
  }


  /**
   * 玩家id获取位置信息 .
   *
   * @author abin
   * @date 2018年3月21日 下午5:06:15
   * @param playerId 玩家id.
   * @return 位置信息.
   */
  public BlackjackSeat getPlayerSeat(long playerId) {
    return playerSeats.get(playerId);
  }


  /**
   * 更新玩家座位 .
   * 
   * @param playerId 玩家id.
   * @param seat 座位.
   */
  public void updatePlayerSeats(long playerId, BlackjackSeat seat) {
    playerSeats.put(playerId, seat);
  }

  /**
   * 移除玩家seat.
   * 
   * @param playerId 玩家id.
   */
  public void removePlayerSeat(long playerId) {
    playerSeats.remove(playerId);
  }


}
